﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace BattleShipPro
{
    public class Session
    {
        public List<BattleShip> BattleShips { get; set; }
        public BattleShip CurrentHitShip { get; set; }
        public event EventHandler Lost;
        private bool[,] _pointsOccupied = new bool[10, 10];

        public Session()
        {
            BattleShips = new List<BattleShip>();
            BattleShips.Add(GetBattleShip(Constants.AircraftCarrier, Constants.AircraftCarrierSpaces));
            BattleShips.Add(GetBattleShip(Constants.BattleShip, Constants.BattleShipSpaces));
            BattleShips.Add(GetBattleShip(Constants.Destroyer, Constants.DestroyerSpaces));
            BattleShips.Add(GetBattleShip(Constants.Submarine, Constants.SubmarineSpaces));
            BattleShips.Add(GetBattleShip(Constants.PatrolBoat, Constants.PatrolBoatSpaces));
        }

        private BattleShip GetBattleShip(string name, int spaces)
        {
            return new BattleShip(name, spaces);
        }

        public void Create()
        {
            var random = new Random();
            foreach (var battleShip in BattleShips)
            {
                var orientation = random.Next(0, 2) == 0 ? Orientation.Horizontal : Orientation.Vertical;
                var startX = random.Next(Constants.BoardSize - 5);
                var startY = random.Next(Constants.BoardSize - 5);

                while (!CheckPlacement(startX, startY, orientation, battleShip.Spaces))
                {
                    startX = random.Next(Constants.BoardSize - 5);
                    startY = random.Next(Constants.BoardSize - 5);
                }

                battleShip.StartX = startX;
                battleShip.StartY = startY;
                battleShip.Orientation = orientation;
                SavePositionInfo(battleShip);
            }
        }

        private void SavePositionInfo(BattleShip battleShip)
        {
            for (int i = 0; i < battleShip.Spaces; i++)
            {
                if (battleShip.Orientation == Orientation.Horizontal)
                {
                    _pointsOccupied[battleShip.StartX + i, battleShip.StartY] = true;
                }
                else
                {
                    _pointsOccupied[battleShip.StartX, battleShip.StartY + i] = true;
                }
            }
        }

        private bool CheckPlacement(int startX, int startY, Orientation orientation, int spaces)
        {
            for (int i = 0; i < spaces; i++)
            {
                if (orientation == Orientation.Horizontal)
                {
                    if (_pointsOccupied[startX + i, startY])
                        return false;
                }
                else
                {
                    if (_pointsOccupied[startX, startY + i])
                        return false;
                }
            }
            return true;
        }

        public bool ReceiveAttack(int x, int y)
        {
            if (HasShip(x, y))
            {
                CheckStatus();
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool HasShip(int x, int y)
        {
            foreach (BattleShip battleShip in BattleShips)
            {
                if (battleShip.IsInPosition(x, y))
                {
                    CurrentHitShip = battleShip;
                    return true;
                }
            }
            return false;
        }


        public void CheckStatus()
        {
            if (!BattleShips.Any(battleShip => battleShip.IsAlive()))
            {
                if (Lost != null)
                {
                    Lost(this, new EventArgs());
                }
            }
        }
    }
}
